home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / SiFLyiNG_10.txt < prev    next >
Encoding:
Text File  |  1999-08-12  |  20.6 KB  |  483 lines

  1.  
  2.         SiFLyiNG
  3.                 Tutorial #10
  4.  
  5. ___________________________________________________________________________
  6.  
  7. Target          : Liquid Crackme 2
  8.                   d/l it on Http://crackmes.cjb.net
  9. Protection type : Code, red herrings ;)
  10. Level           : Basis and discernment are needed
  11. Tools needed    : SoftIce 4 or 3.xx
  12.                   Basis of cracking of course
  13.                   A brain
  14.                   Some punk mp3 like Rancid or Wizo
  15.                   A drink could be very helpful :)
  16.  
  17. ___________________________________________________________________________
  18.  
  19. Before beginning...
  20.  
  21.         Hope you've read my tut 9 on the previous -and first- Liquid Crackme.
  22. This one is based on a code protection. The checking seems very long but
  23. there are lots of red herrins (hope it must be written like that...). In fact,
  24. only 3 chars of the entered code are really checked, that's why i told you
  25. need discernment to find the 'useful' and interesting checking routine.
  26.         I think i've told enough for this introduction. We're now ready to
  27. get rid off this crackme :)
  28. ___________________________________________________________________________
  29.  
  30. The essay...
  31.  
  32.         Run the proggie and you see an unique textbox to complete. Let's
  33. enter a dummy code : '12345678'. We'll suppose in the crackme that the name
  34. is separated in 8 parts : X1X2X3X4X5X6X7X8
  35.         Now 'Bpx hmemcpy' is SoftIce and F5 to come back to the crackme.
  36. Here you press the 'Check!' button. Boom, we're back to SoftIce. Press F11 to
  37. return to the caller, and F12 until you see this at the bottom of the code
  38. window :
  39.  
  40.         SERIAL!CODE+00026261
  41.  
  42.         You should now see this piece of code :
  43.  
  44. :00427261 call 00411AC8         ; this call gets the entered code
  45. :00427266 cmp dword ptr [ebp-04], 00000000 ; [ebp-04] contains the lenght of
  46.                                 the name, so the lenght is compared to 00
  47. :0042726A jne 00427286          ; jump is lenght>0
  48.  
  49.         So the following routine is used when no name was entered :
  50.  
  51. :0042726C push 00000000
  52. :0042726E mov cx, word ptr [00427610]
  53. :00427275 mov dl, 02
  54. :00427277 mov eax, 0042761C ; points to "You must enter something!"
  55. :0042727C call 00426CAC   ; displays a message box 
  56. :00427281 jmp 004275E4    ; jump out of the routine
  57.  
  58.         The few previous lines are also used to prevent that no name was
  59. entered in the TextBox. But we entered '12345678' so we jump over this
  60. routine and the crackme go on checking the code:
  61.  
  62. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  63. |:0042726A(C)  <=> previous jump if name entered 
  64. |
  65. :00427286 lea edx, dword ptr [ebp-04]
  66. :00427289 mov eax, dword ptr [esi+000001C0]
  67. :0042728F call 00411AC8
  68.  
  69.         NB : all the call to 411AC8 are getting a string. So i advise
  70. to disable the breakpoint by 'bd *', otherwise you'll have each time a bpx
  71. on hmemcpy !!!
  72.  
  73. :00427294 mov eax, dword ptr [ebp-04]   ; eax points to the name
  74. :00427297 movzx eax, byte ptr [eax]     ; eax = X1
  75. :0042729A push eax                      ; push the value of 1st char of code
  76. :0042729B lea edx, dword ptr [ebp-08]
  77. :0042729E mov eax, dword ptr [esi+000001AC]
  78. :004272A4 call 00411AC8                 ; get a 'magic' string
  79. :004272A9 mov eax, dword ptr [ebp-08]   ; eax points to this string
  80.  
  81. Another break : the string that i call the 'magic' string is only the
  82. following string: "Registration Information:" which is used all along the
  83. verification. Note you can see this string in the main window of the crackme,
  84. in the upper left corner.
  85.  
  86. :004272AC movzx eax, byte ptr [eax+07]  ; eax = value of 8th char of magic
  87.                                         ; string = value of 'a' = 61h
  88. :004272B0 pop edx                       ; pop the value of 1st char of code
  89. :004272B1 xor edx, eax                  ; edx = X1 xor 61h
  90. :004272B3 mov dword ptr [ebx], edx      ; store edx in [ebx]
  91. :004272B5 lea edx, dword ptr [ebp-04]
  92. :004272B8 mov eax, dword ptr [esi+000001AC]
  93. :004272BE call 00411AC8                 ; get the magic string
  94. :004272C3 mov eax, dword ptr [ebp-04]
  95. :004272C6 movzx eax, byte ptr [eax+0D]  ; eax = value of 14th char of the
  96.                                         ; magic string = 'I' = 49h 
  97. :004272CA xor eax, 00000080             ; eax = 49h xor 80h = C9
  98. :004272CF mov dword ptr [edi], eax      ; store eax in [edi]
  99. :004272D1 mov eax, dword ptr [ebx]      ; eax = X1 xor 61h
  100. :004272D3 not eax                       ; eax = not(X1 xor 61h)
  101. :004272D5 cmp eax, 00000037             ; cmp eax to 37
  102. :004272D8 jne 004272DF                  ; jump if they are differents
  103. :004272DA call 004271EC                 ; call ???
  104.  
  105.         Pfff... what have we got in here ?
  106.         Eax = not(X1 xor 61) must be equal to 37 not to jump ... so let's
  107. calculate X1:
  108.  
  109.         X1 xor 61h = NOT 37h => X1 = 61h xor FFFFFFC8h = FFFFFFA9h
  110.  
  111.       Wtf ?!? Hey how X1 can be equal to FFFFFFC8h if ascii value stop to FF ?
  112. Hummm i suggest to look closer... let's reverse the flag not to jump and make
  113. the crackme believe they are equals ('r fl z'). Arghh! a messagebox tell us:
  114. "Nop! Keep working". So you easily deduce the comparison is a red herring.
  115.         But you wonder : "What's those red herrings ???" I use to answer a
  116. definition made by EB in one of his project :
  117.   "Red herring is something like sending you on a useless path far from the
  118. correct spot. 8)"
  119.  
  120.         You must understand now... we have to avoid all the call 004271EC
  121. that displays each time a bad cracker message box. I mean, we have to ignore
  122. these particular structure :
  123.  
  124. jne XXXXXXXX
  125. call 004271EC                 ; display bad cracker message box
  126.  
  127.         Woohh it eliminates lot of job !!! yes so we can now find the really
  128. interesting part of the code !
  129.         So let's continue :
  130.  
  131. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  132. |:004272D8(C) => this jump is automatically taken
  133. |
  134. :004272DF lea edx, dword ptr [ebp-04]
  135. :004272E2 mov eax, dword ptr [esi+000001C0]
  136. :004272E8 call 00411AC8
  137. :004272ED mov eax, dword ptr [ebp-04]
  138. :004272F0 movzx eax, byte ptr [eax+01]
  139. :004272F4 push eax
  140. :004272F5 lea edx, dword ptr [ebp-08]
  141. :004272F8 mov eax, dword ptr [esi+000001AC]
  142. :004272FE call 00411AC8
  143. :00427303 mov eax, dword ptr [ebp-08]
  144. :00427306 movzx eax, byte ptr [eax+06]
  145. :0042730A pop edx
  146. :0042730B and edx, eax
  147. :0042730D mov dword ptr [ebx], edx
  148. :0042730F lea edx, dword ptr [ebp-04]
  149. :00427312 mov eax, dword ptr [esi+000001AC]
  150. :00427318 call 00411AC8
  151. :0042731D mov eax, dword ptr [ebp-04]
  152. :00427320 movzx eax, byte ptr [eax+0E]
  153. :00427324 xor eax, 0000000E
  154. :00427327 mov dword ptr [edi], eax
  155. :00427329 mov eax, dword ptr [ebx]
  156. :0042732B not eax
  157. :0042732D cmp eax, dword ptr [edi]
  158. :0042732F jne 00427336              ; arghhh the famous structure
  159.                                     ; but it automatically jumps
  160. :00427331 call 004271EC
  161.  
  162.  
  163.         Hey, this method prevents us from studying dummy code :) Just ignore
  164. the previous part and continue and this time it becomes interesting:
  165.  
  166. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  167. |:0042732F(C) => this jump is automatically taken
  168. |
  169. :00427336 lea edx, dword ptr [ebp-04]
  170. :00427339 mov eax, dword ptr [esi+000001C0]
  171. :0042733F call 00411AC8                 ; gets the entered code
  172. :00427344 mov eax, dword ptr [ebp-04]   ; eax points to the code
  173. :00427347 movzx eax, byte ptr [eax+02]  ; eax = X3
  174. :0042734B push eax                      ; push eax on the stack
  175. :0042734C lea edx, dword ptr [ebp-08]
  176. :0042734F mov eax, dword ptr [esi+000001AC]
  177. :00427355 call 00411AC8                 ; get the magic string
  178. :0042735A mov eax, dword ptr [ebp-08]   ; eax points to the magic string
  179. :0042735D movzx eax, byte ptr [eax+05]  ; eax=value of 6th char of the
  180.                                         ; magic string = 't' = 74h
  181. :00427361 pop edx                       ; pop X3 in edx
  182. :00427362 xor edx, eax                  ; edx = X3 xor 74h
  183. :00427364 mov dword ptr [ebx], edx      ; store edx to [ebx]
  184. :00427366 lea edx, dword ptr [ebp-04]
  185. :00427369 mov eax, dword ptr [esi+000001AC]
  186. :0042736F call 00411AC8                 ; gets the magic string
  187. :00427374 mov eax, dword ptr [ebp-04]   ; eax points to the magic string
  188. :00427377 movzx eax, byte ptr [eax+0F]  ; eax= value of 16th char of the
  189.                                         ; magic string = 'f' = 66h
  190. :0042737B xor eax, 00000044             ; eax = 66h xor 44h = 22h
  191. :0042737E mov dword ptr [edi], eax      ; store eax in edi
  192. :00427380 mov eax, dword ptr [ebx]      ; eax = [ebx] = X3 xor 74h
  193. :00427382 cmp eax, dword ptr [edi]      ; cmp eax to [edi]
  194. :00427384 je 0042738B                   ; jump if equal
  195. :00427386 call 004271EC                 ; <= bad cracker msgbox
  196.  
  197.         Hey ! it's differents from the previous cmp, isn't it ? Now it's a je
  198. (means jump if equal), so the jump is taken only if eax=[edi] and it avoids
  199. the bad cracker message, and continue the verification.
  200.         So we must have :
  201.  
  202.         eax=[edi] <=> X3 xor 74h=22h <=> X3=74h xor 22h=56h
  203.  
  204.         However 56h is the ASCII code for char 'V'. Hey it simply means that
  205. X3 must be 'V' and the code X1X2VX4X5X6X7X8... quite a nice beginning :)
  206.         Let's continue:
  207.  
  208. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  209. |:00427384(C) => this jump must be taken !!!
  210. |
  211. :0042738B lea edx, dword ptr [ebp-04]
  212. :0042738E mov eax, dword ptr [esi+000001C0]
  213. :00427394 call 00411AC8
  214. :00427399 mov eax, dword ptr [ebp-04]
  215. :0042739C movzx eax, byte ptr [eax+03]
  216. :004273A0 push eax
  217. :004273A1 lea edx, dword ptr [ebp-08]
  218. :004273A4 mov eax, dword ptr [esi+000001AC]
  219. :004273AA call 00411AC8
  220. :004273AF mov eax, dword ptr [ebp-08]
  221. :004273B2 movzx eax, byte ptr [eax+04]
  222. :004273B6 pop edx
  223. :004273B7 and edx, eax
  224. :004273B9 mov dword ptr [ebx], edx
  225. :004273BB lea edx, dword ptr [ebp-04]
  226. :004273BE mov eax, dword ptr [esi+000001AC]
  227. :004273C4 call 00411AC8
  228. :004273C9 mov eax, dword ptr [ebp-04]
  229. :004273CC movzx eax, byte ptr [eax+10]
  230. :004273D0 xor eax, 0000000E
  231. :004273D3 mov dword ptr [edi], eax
  232. :004273D5 mov eax, dword ptr [ebx]
  233. :004273D7 not eax
  234. :004273D9 cmp eax, dword ptr [edi]
  235. :004273DB jne 004273E2                ; and the famous structure again :)
  236. :004273DD call 004271EC
  237.  
  238.         Hummm... not interesting... another red herring. Let's see what's
  239. afterwards :
  240.  
  241. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  242. |:004273DB(C) => this jump is automatically taken
  243. |
  244. :004273E2 lea edx, dword ptr [ebp-04]
  245. :004273E5 mov eax, dword ptr [esi+000001C0]
  246. :004273EB call 00411AC8
  247. :004273F0 mov eax, dword ptr [ebp-04]
  248. :004273F3 movzx eax, byte ptr [eax+04]
  249. :004273F7 push eax
  250. :004273F8 lea edx, dword ptr [ebp-08]
  251. :004273FB mov eax, dword ptr [esi+000001AC]
  252. :00427401 call 00411AC8
  253. :00427406 mov eax, dword ptr [ebp-08]
  254. :00427409 movzx eax, byte ptr [eax+03]
  255. :0042740D pop edx
  256. :0042740E xor edx, eax
  257. :00427410 mov dword ptr [ebx], edx
  258. :00427412 lea edx, dword ptr [ebp-04]
  259. :00427415 mov eax, dword ptr [esi+000001AC]
  260. :0042741B call 00411AC8
  261. :00427420 mov eax, dword ptr [ebp-04]
  262. :00427423 movzx eax, byte ptr [eax+11]
  263. :00427427 xor eax, 00000057
  264. :0042742A mov dword ptr [edi], eax
  265. :0042742C mov eax, dword ptr [ebx]
  266. :0042742E not eax
  267. :00427430 cmp eax, 00000025
  268. :00427433 jne 0042743A             ; the famous structure again and again :)
  269. :00427435 call 004271EC
  270.  
  271.         Let's ignore this piece of code too: red herring !!! Let's continue
  272.  
  273. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  274. |:00427433(C) => automatically taken
  275. |
  276. :0042743A lea edx, dword ptr [ebp-04]
  277. :0042743D mov eax, dword ptr [esi+000001C0]
  278. :00427443 call 00411AC8
  279. :00427448 mov eax, dword ptr [ebp-04]
  280. :0042744B movzx eax, byte ptr [eax+05]
  281. :0042744F push eax
  282. :00427450 lea edx, dword ptr [ebp-08]
  283. :00427453 mov eax, dword ptr [esi+000001AC]
  284. :00427459 call 00411AC8
  285. :0042745E mov eax, dword ptr [ebp-08]
  286. :00427461 movzx eax, byte ptr [eax+02]
  287. :00427465 pop edx
  288. :00427466 and edx, eax
  289. :00427468 mov dword ptr [ebx], edx
  290. :0042746A lea edx, dword ptr [ebp-04]
  291. :0042746D mov eax, dword ptr [esi+000001AC]
  292. :00427473 call 00411AC8
  293. :00427478 mov eax, dword ptr [ebp-04]
  294. :0042747B movzx eax, byte ptr [eax+12]
  295. :0042747F xor eax, 0000000C
  296. :00427482 mov dword ptr [edi], eax
  297. :00427484 mov eax, dword ptr [ebx]
  298. :00427486 not eax
  299. :00427488 cmp eax, dword ptr [edi]
  300. :0042748A jne 00427491               ; arghhhh another time the same structure
  301. :0042748C call 004271EC
  302.  
  303.         Ok another red herring !!! but the next piece of code is a good one
  304. time. The jne is no more a jne, but a je, so we have to study it attentively:
  305.  
  306. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  307. |:0042748A(C) => automatically taken too
  308. |
  309. :00427491 lea edx, dword ptr [ebp-04]
  310. :00427494 mov eax, dword ptr [esi+000001C0]
  311. :0042749A call 00411AC8                     ; get the entered code
  312. :0042749F mov eax, dword ptr [ebp-04]       ; eax points to the code
  313. :004274A2 movzx eax, byte ptr [eax+06]      ; eax = X7
  314. :004274A6 push eax                          ; push eax on the stack
  315. :004274A7 lea edx, dword ptr [ebp-08]
  316. :004274AA mov eax, dword ptr [esi+000001AC]
  317. :004274B0 call 00411AC8                     ; get the magic string
  318. :004274B5 mov eax, dword ptr [ebp-08]       ; eax points to the magic string
  319. :004274B8 movzx eax, byte ptr [eax+01]      ; eax = value of 2nd char of the
  320.                                             ; magic string = 'e' = 65h
  321. :004274BC pop edx                           ; pop edx => edx = X7
  322. :004274BD xor edx, eax                      ; edx = X7 xor 65h
  323. :004274BF mov dword ptr [ebx], edx          ; store edx in [ebx]
  324. :004274C1 lea edx, dword ptr [ebp-04]
  325. :004274C4 mov eax, dword ptr [esi+000001AC]
  326. :004274CA call 00411AC8                     ; get the magic string
  327. :004274CF mov eax, dword ptr [ebp-04]       ; eax points to the magic string
  328. :004274D2 movzx eax, byte ptr [eax+13]      ; eax = value of 20th char of the
  329.                                             ; magic string = 'a' = 61h    
  330. :004274D6 xor eax, 00000049                 ; eax = 61h xor 49h = 28h
  331. :004274D9 mov dword ptr [edi], eax          ; store eax in [edi]
  332. :004274DB cmp dword ptr [ebx], 00000028     ; cmp [ebx] to 28h
  333. :004274DE je 004274E5                       ; hey a je this time :)
  334. :004274E0 call 004271EC                     ; <= bad cracker message
  335.  
  336.         You easily understand that the jump must be taken here to avoid this
  337. boring bad cracker message. So we mus have to take the jump:
  338.  
  339.         [ebx]=28 <=> X7 xor 65h=28h <=> X7=65h xor 28h=4Dh
  340.  
  341.         However 4D is the ascii hexa code for 'M'. So X7 must be 'M' and the
  342. serial now becomes X1X2VX4X5X6MX8... Let's see the following :
  343.  
  344. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  345. |:004274DE(C) => this jump must be taken
  346. |
  347. :004274E5 lea edx, dword ptr [ebp-04]
  348. :004274E8 mov eax, dword ptr [esi+000001C0]
  349. :004274EE call 00411AC8                     ; get the entered code
  350. :004274F3 mov eax, dword ptr [ebp-04]       ; eax points to the code
  351. :004274F6 movzx eax, byte ptr [eax+07]      ; eax = X8
  352. :004274FA push eax                          ; push eax
  353. :004274FB lea edx, dword ptr [ebp-08]
  354. :004274FE mov eax, dword ptr [esi+000001AC]
  355. :00427504 call 00411AC8                     ; get the magic string
  356. :00427509 mov eax, dword ptr [ebp-08]       ; eax points to the string
  357. :0042750C movzx eax, byte ptr [eax]         ; eax = value of 1st char of the
  358.                                             ; magic string = 'R' = 52h
  359. :0042750F pop edx                           ; pop edx => edx = X8
  360. :00427510 and edx, eax                      ; edx = X8 and 52h
  361. :00427512 mov dword ptr [ebx], edx          ; edx is stored in [ebx]
  362. :00427514 lea edx, dword ptr [ebp-04]
  363. :00427517 mov eax, dword ptr [esi+000001AC]
  364. :0042751D call 00411AC8                     ; get the magic string
  365. :00427522 mov eax, dword ptr [ebp-04]       ; eax points to the magic string
  366. :00427525 movzx eax, byte ptr [eax+14]      ; eax = value of 21th char of the
  367.                                             ; magic string = 't' = 74h
  368. :00427529 xor eax, 00000024                 ; eax = 74h xor 24h = 50h
  369. :0042752C mov dword ptr [edi], eax          ; eax is stored in [edi]
  370. :0042752E cmp dword ptr [ebx], 00000050     ; cmp [ebx] to 50h
  371. :00427531 je 00427538                       ; jump if they are equal
  372. :00427533 call 004271EC                     ; bad cracker message
  373.  
  374.         Interesting part too... {ebx] is finally compared to 50h, and they
  375. must be equal to take the jump, what is necessary. So we must have:
  376.  
  377.         [ebx]=50h <=> X8 and 52h=50h <=> X8= 50h and 52h=50h
  378.  
  379.         And we know that 50h is the ascii value for the char 'P'
  380.  
  381. We know now that the serial must look like X1X2VX4X5X6MP, where X1,X2... are
  382. variables.
  383.  
  384.         Let's see what happen afterwards :
  385.  
  386. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  387. |:00427531(C) => this jump must be taken !!!
  388. |
  389. :00427538 lea edx, dword ptr [ebp-04]
  390. :0042753B mov eax, dword ptr [esi+000001C0]
  391. :00427541 call 00411AC8                     ; get the entered code
  392. :00427546 mov eax, dword ptr [ebp-04]       ; eax points to the code
  393. :00427549 cmp byte ptr [eax+08], 45         ; cmp X9 to 45h
  394. :0042754D je 0042755E                       ; jump to 42755E if equal
  395. :0042754F mov eax, dword ptr [esi+000001B4]
  396. :00427555 mov bx, FFF5
  397. :00427559 call 00402A0C                     ; display About box
  398.  
  399.          Here X9 must be equal to 45h, i.e. to 'E' in order to jump over
  400. the call that display the msgbox. I imagine that we have to jump and avoid
  401. the about box. So the serial become X1X2VX4X5X6PME
  402.  
  403. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  404. |:0042754D(C)   ; we arrive here after the jump
  405. |
  406. :0042755E lea edx, dword ptr [ebp-04]
  407. :00427561 mov eax, dword ptr [esi+000001C0]
  408. :00427567 call 00411AC8                     ; get the entered code
  409. :0042756C mov eax, dword ptr [ebp-04]       ; eax points to the code
  410. :0042756F cmp byte ptr [eax+09], 72         ; cmp X10 to 72h
  411. :00427573 je 00427584                       ; jump if equal
  412. :00427575 mov eax, dword ptr [esi+000001B4]
  413. :0042757B mov bx, FFF5
  414. :0042757F call 00402A0C                     ; display the About Box
  415.  
  416. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  417. |:00427573(C)
  418. |
  419. :00427584 lea edx, dword ptr [ebp-04]
  420. :00427587 mov eax, dword ptr [esi+000001C0]
  421. :0042758D call 00411AC8                     ; get the entered code
  422. :00427592 mov eax, dword ptr [ebp-04]       ; eax points to the code
  423. :00427595 cmp byte ptr [eax+0A], 54         ; cmp X11 to 54h
  424. :00427599 je 004275AA                       ; jump if equal
  425. :0042759B mov eax, dword ptr [esi+000001B4]
  426. :004275A1 mov bx, FFF5
  427. :004275A5 call 00402A0C                     ; display the about box
  428.  
  429. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  430. |:00427599(C)
  431. |
  432. :004275AA lea edx, dword ptr [ebp-04]
  433. :004275AD mov eax, dword ptr [esi+000001C0]
  434. :004275B3 call 00411AC8                     ; get the entered code
  435. :004275B8 mov eax, dword ptr [ebp-04]       ; eax points to the code
  436. :004275BB cmp byte ptr [eax+0B], 65         ; cmp X12 to 65h
  437. :004275BF je 004275D0                       ; jump if equal
  438. :004275C1 mov eax, dword ptr [esi+000001B4]
  439. :004275C7 mov bx, FFF5
  440. :004275CB call 00402A0C                     ; display the about box
  441.  
  442.         Here are the last lines of the verification of the serial. We can
  443. deduce the last char of the good code :
  444.  
  445.         X9 = 45h = 'E'
  446.         X10= 72h = 'r'
  447.         X11= 54h = 'T'
  448.         X12= 65h = 'e'
  449.  
  450.         and the serial finally becomes X1X2VX4X5X6PMErTe, where X1,X2,...X6
  451. are variables
  452.         
  453. Enter any code like : 12V456MPErTe or SiVFLyMPErTeiNG 
  454. Then the crackme display a little message box and no About box is displayed :
  455.  
  456.         "Cracked"
  457.         "Great job cracker! Well done!"
  458.         "Mail me..."
  459.  
  460.         Hey, cracked cracked !!! ;)
  461.  
  462. ___________________________________________________________________________
  463.  
  464. The end...
  465.  
  466.         Waouhh... this tutorial was quite long i know... i believe i could
  467. have made it shorter but this is not really difficult and there are lots of
  468. red herrings (useless pieces of code !!!). I could have erase them and ignore
  469. them even in the tutor but i wanted to show all the steps i've followed...
  470.         If you have questions, or critics, just mail me...
  471.  
  472.                 SiFLyiNG
  473.                         siflying@ifrance.com
  474.  
  475.         Greetz : ACiD BuRN, Eternal Bliss, Magic Raphoun, Lucifer48,
  476.                 Skymarshall, Volatility, VisionZ, AB4DS
  477.                 all the authors of crackmes and tutorials
  478.                 and Liquid of course for his nice crackme :)
  479.  
  480. PS : I'm looking for Win32asm source for keygen and crackmes... if you have
  481.      some please mail them...
  482.  
  483.